/********************************************
 * 功能说明: RSA工具类
 * 模块名称: 通用工具模块
 * 系统名称: java敏捷开发通用平台
 * 软件版权:
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2016年12月23日 下午9:15:41
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.codec;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * RSA工具类
 * @author zhangfb
 * @version 1.0.0.1
 */
public class RSAUtils {

    private static Map<String, RSAPublicKey> publicKeyMap = new HashMap<String, RSAPublicKey>();
    private static Map<String, RSAPrivateKey> privateKeyMap = new HashMap<String, RSAPrivateKey>();

    public static void main(String[] args) throws Exception {
        String filepath = "D:/tmp/";
        // 生成RSA秘钥文件
        //RSAEncrypt.genKeyPair(filepath);

        // 加载RSA秘钥文件
        String publicKeyStr = RSAEncrypt.loadPublicKeyByFile(filepath);
        String privateKeyStr = RSAEncrypt.loadPrivateKeyByFile(filepath);
        System.out.println("公钥：" + publicKeyStr);
        System.out.println("私钥：" + privateKeyStr);

        String content = privateKeyStr;
        String signStr = RSAUtils.sign(content, privateKeyStr);
        System.out.println("签名：" + signStr);

        boolean ret = RSAUtils.checkSign(publicKeyStr, content, signStr);
        System.out.println("验签：" + ret);

    }
    public static void main2(String[] args) throws Exception {
        String filepath = "D:/tmp/";
        // 生成RSA秘钥文件
        RSAEncrypt.genKeyPair(filepath);

        // 加载RSA秘钥文件
        String publicKeyStr = RSAEncrypt.loadPublicKeyByFile(filepath);
        String privateKeyStr = RSAEncrypt.loadPrivateKeyByFile(filepath);
        System.out.println("公钥：" + publicKeyStr);
        System.out.println("私钥：" + privateKeyStr);

        System.out.println("--------------公钥加密私钥解密过程-------------------");
        String plainText = "aghoo_公钥加密私钥解密";
        // 公钥加密
        String cipherText = RSAUtils.encryptByPublicKey(plainText, publicKeyStr);
        // 私钥解密
        String PlainText2 = RSAUtils.decryptByPrivateKey(cipherText, privateKeyStr);
        System.out.println("原文：" + plainText);
        System.out.println("密文：" + cipherText);
        System.out.println("解密：" + PlainText2);
        System.out.println();

        System.out.println("--------------私钥加密公钥解密过程-------------------");
        plainText = "aghoo_私钥加密公钥解密";
        // 私钥加密
        cipherText = RSAUtils.encryptByPrivateKey(plainText, privateKeyStr);
        // 公钥解密
        PlainText2 = RSAUtils.decryptByPublicKey(cipherText, publicKeyStr);
        System.out.println("原文：" + plainText);
        System.out.println("密文：" + cipherText);
        System.out.println("解密：" + PlainText2);
        System.out.println();

        System.out.println("---------------私钥签名过程------------------");
        String content = "aghoo_这是用于签名的原始数据";
        String signstr = RSASignature.sign(content, privateKeyStr);
        System.out.println("原文：" + content);
        System.out.println("签名：" + signstr);
        System.out.println();

        System.out.println("---------------公钥验签过程------------------");
        System.out.println("原文：" + content);
        System.out.println("签名：" + signstr);

        System.out.println("验签结果：" + RSASignature.checkSign(content, signstr, publicKeyStr));
        System.out.println();
    }

    /**
     * 获取RSA公钥
     * @param publicKeyStr
     * @return
     */
    public static RSAPublicKey getPublicKey(String publicKeyStr) throws Exception {
        RSAPublicKey publicKey = publicKeyMap.get(publicKeyStr);
        if (publicKey == null) {
            publicKey = RSAEncrypt.loadPublicKeyByStr(publicKeyStr);
            publicKeyMap.put(publicKeyStr, publicKey);
        }
        return publicKey;
    }

    /**
     * 获取RSA私钥
     * @param privateKeyStr
     * @return
     */
    public static RSAPrivateKey getPrivateKey(String privateKeyStr) throws Exception {
        RSAPrivateKey privateKey = privateKeyMap.get(privateKeyStr);
        if (privateKey == null) {
            privateKey = RSAEncrypt.loadPrivateKeyByStr(privateKeyStr);
            privateKeyMap.put(privateKeyStr, privateKey);
        }
        return privateKey;
    }

    /**
     * RSA私钥加密
     * @param privateKeyStr
     * @param plainText
     * @return
     * @throws Exception
     */
    public static String encryptByPrivateKey(String plainText, String privateKeyStr) throws Exception {
        RSAPrivateKey privateKey = getPrivateKey(privateKeyStr);
        return RSAEncrypt.encrypt(privateKey, plainText);
    }

    /**
     * RSA公钥解密
     * @param cipherText
     * @param publicKeyStr
     * @return
     * @throws Exception
     */
    public static String decryptByPublicKey(String cipherText, String publicKeyStr) throws Exception {
        RSAPublicKey publicKey = getPublicKey(publicKeyStr);
        return RSAEncrypt.decrypt(publicKey, cipherText);
    }

    /**
     * RSA公钥加密
     * @param plainText
     * @param publicKeyStr
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKey(String plainText, String publicKeyStr) throws Exception {
        RSAPublicKey publicKey = getPublicKey(publicKeyStr);
        return RSAEncrypt.encrypt(publicKey, plainText);
    }

    /**
     * RSA私钥解密
     * @param cipherText
     * @param privateKeyStr
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKey(String cipherText, String privateKeyStr) throws Exception {
        RSAPrivateKey privateKey = getPrivateKey(privateKeyStr);
        return RSAEncrypt.decrypt(privateKey, cipherText);
    }

    /**
     * RSA私钥签名
     * @param content 待签名数据
     * @param privateKeyStr RSA私钥
     * @return 签名值
     */
    public static String sign(String content, String privateKeyStr) throws Exception {
        return RSASignature.sign(content, privateKeyStr);
    }

    /**
     * RSA公钥验签
     * @param content 已签名数据
     * @param signStr 签名值
     * @param publicKeyStr RSA公钥
     * @return 布尔值
     */
    public static boolean checkSign(String publicKeyStr, String content, String signStr) {
        return RSASignature.checkSign(content, signStr, publicKeyStr);
    }
}
